/**
 * @class
 * @memberof ScLibs.ui
 * @property {jQuery} el jquery 오브젝트
 * @property {Number} config.activeIndex 초기 활성화될 탭의 index. 기본값 : 0
 * @property {String} config.transition 기본 애니메이션. 기본값 : "slide"
 * @desc 탭형태의 UI 를 생성한다. 다음과 같은 애니메이션이 있다.
 * <ul><li>slide</li><li>slidedown</li><li>slideup</li><li>slidefade</li><li>pop</li><li>fade</li><li>flip</li></ul>
 * @example
 * var tabs = new ScLibs.ui.Tabs($("#tabs"), {
 *		activeIndex: 0,
 *		transition: 'slide'
 * });
 * tabs.on("change", function(){ })
 */
ScLibs.ui.Tabs = ScLibs.extend(ScLibs.Observer, {
	initialize: function(el, config){
		this.config = {
			autoRender: true,
			activeIndex: 0,
			transition: 'slide'
		};

		this.config = $.extend(this.config, config);
		
		var listener = { };
		if(this.config.listener){
			listener = this.config.listener;
		}
		ScLibs.ui.Tabs.base.initialize.call(this, this.listener);

		this.el = el;
		this.activeIndex = this.config.activeIndex;

		if(this.config.autoRender){
			this.render();
		}
	},
	render: function(){
		this.el.addClass("ui-tabs");
		this.panels = this.el.children("div").addClass("ui-tabs-panel");
		this.nav = this.el.children("ul").find("a");
		
		this.panels.eq(this.config.activeIndex).addClass("ui-tabs-panel-active");

		this.nav.on('click', $.proxy(this._click, this));
	},
	_click: function(e){
		var src = $(e.originalEvent.srcElement),
			index = this.nav.index(src);

		this.change(index);
		return false;
	},
	/**
	 * @method
	 * @memberof ScLibs.ui.Tabs.prototype
	 * @param {Number} index 전환할 탭의 index
	 * @desc 현재 활성화된 탭을 전환한다.
	 */
	change: function(index){
		var oldIndex = this.getActiveIndex(),
			newIndex = index;
		
		if(oldIndex === newIndex){
			return;
		}
		
		if(newIndex > oldIndex){
			this.right(this.panels.eq(newIndex), this.panels.eq(oldIndex), index);
		}
		else{
			this.left(this.panels.eq(newIndex), this.panels.eq(oldIndex), index);
		}
	},
	right: function(newPanel, oldPanel, index){
		var promise = this.transitionStart(newPanel, oldPanel, this.config.transition, '');
		promise.done($.proxy(function(){
			oldPanel.removeClass("ui-tabs-panel-active");
			this.setActiveIndex(index);
			
			this.changeEvent();
		}, this));
	},
	left: function(newPanel, oldPanel, index){
		var promise = this.transitionStart(newPanel, oldPanel, this.config.transition, 'reverse');
		promise.done($.proxy(function(){
			oldPanel.removeClass("ui-tabs-panel-active");
			this.setActiveIndex(index);

			this.changeEvent();
		}, this));
	},
	changeEvent: function(){
		this.fireEvent(this, 'change', [this, this.getActiveIndex(index)]);
	},
	transitionStart: function(newPanel, oldPanel, transition, reverse){
		var deferred = new $.Deferred();

		function transitionHandler(newPanel, oldPanel, transition, reverse){
			var viewIn = function(){
				newPanel
					.addClass(transition + ' in ' + reverse + ' ui-transitioning ui-tabs-panel-active');
				
				oldPanel
					.addClass(transition + ' out ' + reverse + ' ui-transitioning');
			
				if(transition !== 'none'){
					newPanel.one("webkitAnimationEnd", viewOut);
				}
				else{
					viewOut();
				}
			},
			viewOut = function(){
				newPanel.removeClass(transition + ' in ' + reverse + ' ui-transitioning');
				oldPanel.removeClass(transition + ' out ' + reverse + ' ui-transitioning');

				done();
			},
			done = function(){
				deferred.resolve();
				newPanel = null, oldPanel = null, transition = null, reverse = null;
			};
			viewIn();
		}
		transitionHandler(newPanel, oldPanel, transition, reverse);

		return deferred;
	},
	/**
	 * @method
	 * @memberof ScLibs.ui.Tabs.prototype
	 * @return {Number} index 현재 활성화된 탭의 index
	 * @desc 현재 활성화된 탭의 index 를 반환한다.
	 */
	getActiveIndex: function(){
		return this.activeIndex;
	},
	setActiveIndex: function(index){
		this.activeIndex = index;
	}
});

